// --- Copyright (c) 2006-2008 Stefan Kyntchev ---
// This software is written and copyrighted by Stefan Kyntchev 
// and BeyondPod Team members. All rights are reserved.
// Author contact: support@beyondpod.mobi
// ------------------------------------------------------------------------
// This file is part of BeyondPod RSS Feed Reader and Podcast manager
// (www.codeplex.com/BeyondPod) 
// BeyondPod is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
//  
// BeyondPod is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
// GNU General Public License for more details. 
//  
// You should have received a copy of the GNU General Public License
// along with BeyondPod. If not, see <http://www.gnu.org/licenses/>
// ------------------------------------------------------------------------
// COPYRIGHT NOTICE: This copyright notice may NOT be removed, obscured or modified 
// without written consent from the author.
// --- End copyright notice --- 


using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace svs.Mobile.BeyondScheduler.Core.Objects.Operations
{
	public class OperationWiFi : OperationBase, IEquatable<OperationWiFi>
	{
		#region WiFiAction enum

		public enum WiFiAction
		{
			On,
			Off
		}

		#endregion

		public static readonly Guid OperationID = new Guid("{C1E069B3-2CDC-4b89-BC53-0FDE734D61B9}");

		private WiFiAction _TurnTo = WiFiAction.Off;

		public OperationWiFi() : base("Turn WiFi", "Turn WiFi On or Off", OperationID)
		{
		}

		public OperationWiFi(WiFiAction action)
			: this()
		{
			TurnTo = action;
		}

		public override string Name
		{
			get { return base.Name + " " + TurnTo.ToString(); }
		}

		public WiFiAction TurnTo
		{
			get { return _TurnTo; }
			set { _TurnTo = value; }
		}


		/// <summary>
		/// Serilized state of teh Operation
		/// </summary>
		public override string SerializedData
		{
			get { return (TurnTo).ToString(); }
		}

		public override string Description
		{
			get { return Name; }
		}

		public bool Equals(OperationWiFi operationWiFi)
		{
			if (operationWiFi == null) return false;
			return Equals(_TurnTo, operationWiFi._TurnTo);
		}

		public override void Execute()
		{
			base.Execute();
			if (TurnTo == WiFiAction.Off)
				WifiOff();
			else
				WifiOn();
		}

		/// <summary>
		/// Creates an instance of the this operation, desrialized from the serilaized string
		/// </summary>
		/// <param name="serializadData"></param>
		/// <returns></returns>
		public override OperationBase CreateInstance(string serializadData)
		{
			WiFiAction action = WiFiAction.Off;

			if (!string.IsNullOrEmpty(serializadData))
				action = (WiFiAction) Enum.Parse(typeof (WiFiAction), serializadData, true);

			return new OperationWiFi(action);
		}

		public override bool Equals(object obj)
		{
			if (ReferenceEquals(this, obj)) return true;
			return Equals(obj as OperationWiFi);
		}

		public override int GetHashCode()
		{
			return _TurnTo.GetHashCode();
		}

		#region WiFi Interface

		[DllImport("coredll")]
		private static extern int SetDevicePower(string pvDevice, int Flags, PowerState state);

		[DllImport("coredll")]
		private static extern int DevicePowerNotify(string name, PowerState state, int flags);


		public void WifiOn()
		{
			string[] names = getWirelessAdapterNameThroughRegistry();
			string regKey = getRegistryKey();

			foreach (string name in names)
			{
				if (name.IndexOf(regKey) != -1)
				{
					DevicePowerNotify(name, PowerState.D0, 0x00000001);
					SetDevicePower(name, 1, PowerState.D0);

					return;
				}
			}
		}


		public void WifiOff()
		{
			string[] names = getWirelessAdapterNameThroughRegistry();
			string regKey = getRegistryKey();

			foreach (string name in names)
			{
				if (name.IndexOf(regKey) != -1)
				{
					DevicePowerNotify(name, PowerState.D4, 1);
					SetDevicePower(name, 1, PowerState.D4);

					return;
				}
			}
		}


		private string getRegistryKey()
		{
			RegistryKey OurKey = Registry.LocalMachine;
			string[] subkey = OurKey.OpenSubKey("System\\CurrentControlSet\\Control\\Power\\State\\Suspend").GetSubKeyNames();
			return subkey.GetValue(0).ToString();
		}

		private string[] getWirelessAdapterNameThroughRegistry()
		{
			RegistryKey OurKey = Registry.LocalMachine;
			string[] names = OurKey.OpenSubKey("System\\CurrentControlSet\\Control\\Power\\State").GetValueNames();
			return names;
		}

		private enum PowerState
		{
			PwrDeviceUnspecified = -1,
			D0 = 0, // Full On: full power, full functionality
			D1 = 1, // Low Power On: fully functional at low power/performance
			D2 = 2, // Standby: partially powered with automatic wake
			D3 = 3, // Sleep: partially powered with device initiated wake
			D4 = 4, // Off: unpowered
			PwrDeviceMaximum = 5
		}

		#endregion
	}
}